Skip to content

MC: Ability to process empty timeframes (Part 1) - #15705

Open
sawenzel wants to merge 5 commits into
AliceO2Group:devfrom
sawenzel:sawenzel/colcontext-empty-tf
Open

MC: Ability to process empty timeframes (Part 1)#15705
sawenzel wants to merge 5 commits into
AliceO2Group:devfrom
sawenzel:sawenzel/colcontext-empty-tf

Conversation

@sawenzel

@sawenzel sawenzel commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Fix of problems with empty timeframe handling in

  • collision context
  • tpc loopers
  • digitizer

It it is one step towards successful completion of the compute chain when we have an empty timeframe. Currently we fault for one or another reason and the GRID jobs crash. This shouldn't be the case: In cases when one timeframe is empty, an empty AOD should be produced instead.

@sawenzel
sawenzel force-pushed the sawenzel/colcontext-empty-tf branch from 6d91a54 to 41757d6 Compare August 24, 2026 11:15
@sawenzel sawenzel changed the title Fix instabilities when we have empty timeframes due low interaction rate MC: Ability to process empty timeframes (Part 1) Aug 24, 2026
sawenzel and others added 2 commits August 24, 2026 13:27
This fixes a problem in the timeframe index structure of the collision
context and adds a unit test.

- getTimeFrameBoundaries closed only one timeframe per collision, so a
  timeframe without collisions was left out of the index structure
  entirely and the collisions after it were assigned to the wrong
  timeframe.
- The number of extracted per-timeframe contexts was therefore the number
  of non-empty timeframes, not the number of timeframes asked for, and
  the last tf<N>/collisioncontext.root could be missing.
- The scan now closes every timeframe a collision skips over and pads the
  result to the number of timeframes the caller asks for, so entry i always
  describes orbits [start + i*orbitsPerTF, start + (i+1)*orbitsPerTF).
- applyMaxCollisionFilter keeps an empty timeframe empty when it re-indexes,
  and extractSingleTimeframe returns a valid empty context for it.
- o2-steer-colcontexttool passes the number of timeframes it asked for,
  reports timeframes that came out empty together with the mean number of
  collisions per timeframe implied by the interaction rate, and refuses to
  continue when --noEmptyTF was requested.

https://its.cern.ch/jira/browse/O2-7132

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This fixes a problem in GenTPCLoopers::setFlatGas when the collision
context of a timeframe is empty.

- A timeframe holds no collision whenever the interaction rate is low
  enough, and the generator called exit(1) on it.
- The extent of the timeframe now comes from HBFUtils in that case, which
  is where it is defined, instead of from the last collision.
- With a single collision in the timeframe the mean interaction spacing
  was divided by zero; it is now taken from the interaction rate stored in
  the collision context.

https://its.cern.ch/jira/browse/O2-7132

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sawenzel and others added 3 commits August 24, 2026 13:27
This fixes a segmentation fault in MCHDPLDigitizerTask when the collision
context of a timeframe is empty.

- The noise-only signal range was taken from eventRecords.front() and
  eventRecords.back(), which is undefined behaviour on an empty vector.
- A timeframe holds no collision whenever the interaction rate is low.
- The range now comes from HBFUtils in that case, so the noise covers the
  timeframe that is actually being digitised.

https://its.cern.ch/jira/browse/O2-7132

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This fixes the TPC digit writer producing a file without a tree when a
timeframe holds no collision.

- The custom close callback only called TFile::Close inside "if (entries >
  0)", and never called TFile::Write, so with nothing to write the tree
  never reached the file.
- The result was a 942 byte file with no o2sim tree, and every reader of it
  failed on a missing branch rather than on an empty tree.
- Each branch is now filled once with the empty default object it is bound
  to, so the file is an ordinary timeframe that happens to contain no digit
  and the readers downstream stay on their normal path.
- The tree is written explicitly, the way RootTreeWriter's own close does.

https://its.cern.ch/jira/browse/O2-7132

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This fixes the digit file of a timeframe without collisions carrying a label
branch of the wrong type.

- The MC label branch is declared as std::vector<char> and only becomes an
  IOMCTruthContainerView when a fill remaps it.
- With no collision nothing is filled, the branch keeps the raw type, and a
  reader binding IOMCTruthContainerView gets a class mismatch from
  SetBranchAddress rather than an empty tree.
- The close callback now writes one empty entry in every branch, remapping
  the label branch on the way, so the file has the same shape as an ordinary
  timeframe that happens to contain nothing.

https://its.cern.ch/jira/browse/O2-7132

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sawenzel
sawenzel force-pushed the sawenzel/colcontext-empty-tf branch from 41757d6 to 3f49e82 Compare August 24, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant